package com.uuah.server.channel;

import com.uuah.exception.lifecycle.InitialisationException;
import com.uuah.server.api.IUuahContext;
import com.uuah.server.api.IUuahEvent;
import com.uuah.server.api.IUuahMessage;
import com.uuah.server.api.channel.IChannel;
import com.uuah.server.api.context.IUuahContextAware;
import com.uuah.server.api.endpoint.IUuahEndpoint;
import com.uuah.server.config.Constants;
import com.uuah.server.exception.AbstractUuahServerException;
import com.uuah.server.exception.MessagingException;
import com.uuah.server.exception.channel.RoutingException;
import com.uuah.utils.StringUtils;

public class DefaultChannel implements IChannel, IUuahContextAware {

	protected IUuahContext uuahContext;
	protected IUuahEndpoint uuahEndpoint;

	public void initialise() throws InitialisationException {
		// default impl does nothing
	}

	public void dispose() {
		// Template
	}

	public void setUuahContext(IUuahContext context) {
		this.uuahContext = context;
	}

	public IUuahContext getUuahContext() {
		return uuahContext;
	}

	public void dispatch(IUuahEvent event) throws AbstractUuahServerException {
		event.getSession().dispatchEvent(event);
	}

	public IUuahMessage send(IUuahEvent event) throws AbstractUuahServerException {
		return event.getSession().sendEvent(event);
	}

	public IUuahMessage route(IUuahEvent event) throws MessagingException {
		String requestEndpoint = event.getEndpoint().getName();

		if (StringUtils.isBlank(requestEndpoint)) {
			requestEndpoint = event.getEndpoint().getEndpointURI().getUri()
					.toString();
		}
		event.getMessage().setProperty(
				Constants.UUAH_ORIGINATING_ENDPOINT_PROPERTY, requestEndpoint);

		try {
			IUuahMessage messageResult = null;

			if (event.getMessage().getProperty(
					Constants.UUAH_ORIGINATING_ENDPOINT_PROPERTY) == null) {
				event.getMessage().setProperty(
						Constants.UUAH_ORIGINATING_ENDPOINT_PROPERTY,
						requestEndpoint);
			}

			if (event.isSynchronous()) {
				messageResult = send(event);
			} else {
				dispatch(event);
			}

			return messageResult;
		} catch (AbstractUuahServerException e) {
			throw new RoutingException(event.getMessage(), event.getEndpoint(),
					e);
		}
	}

	public IUuahEndpoint getEndpoint() {
		return uuahEndpoint;
	}

	public void setEndpoint(IUuahEndpoint uuahEndpoint) {
		this.uuahEndpoint = uuahEndpoint;
	}
}
